﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 泛型01
{
    // 泛型将类型作为参数进行传递，在创建类型的时候使用T来作为一个占位符，代替实际的操作类型，等待实例化的时候用一个实际的类型来代替
    class Program//<T> where T : class // 泛型的约束
    {
        static void Main(string[] args)
        {
            // 广泛的类型——代表所有类型

            //Swap(4, 5);
            //Program<int> p = new Program<int>();
            //p.Swap(4, 5);

            //Program<string, int> ps = new Program<string, int>();
            //Program<string> ps = new Program<string>();
            MyClass<string> ps = new MyClass<string>();
            ps.Swap("qwert", "asdfg");

            //Program<int>.Swap(1, 2);

            // 使用泛型可以最大程度的重用代码，保护类型的安全性，提高性能
            // 降低了强制类型转换或装箱操作的成本和风险
            // 可以对泛型进行约束以访问特定数据类型的方法

            // 不能这样使用
            // Program<T> t = new Program<T>();
        }
        //public void Swap(T a, U b)
        //{

        //}

        

        //public static void Swap(int a, int b)
        //{
        //    int temp = a;
        //    a = b;
        //    b = temp;
        //}
        //public static void Swap(string a, string b)
        //{
        //    string temp = a;
        //    a = b;
        //    b = temp;
        //}
        //public static void Swap(double a, double b)
        //{
        //    double temp = a;
        //    a = b;
        //    b = temp;
        //}

        //public static void Swap(object a, object b)
        //{
        //    object temp = a;
        //    a = b;
        //    b = temp;
        //}
    }

    class MyClass<T>
    {
        public void Swap(T a, T b)
        {
            T temp = a;
            a = b;
            b = temp;
            // 因为泛型成员确切类型不确定，可能是类、结构体、字符、字符串、整型、浮点型、枚举
            // 所以不能使用算数运算符、比较运算符等进行运算
            //a + b;
        }
    }
}
